home *** CD-ROM | disk | FTP | other *** search
/ Stone Design / Stone Design.iso / Stone_Friends / Wave / WavesWorld / Source / IBPalettes / WWTCLKit / WWButtonCell.m < prev    next >
Encoding:
Text File  |  1995-03-22  |  15.3 KB  |  555 lines

  1.  
  2. #import "WWButton.h"
  3. #import "WWButtonCell.h"
  4. #import "WWTCLInterp.h"
  5.  
  6. #import "avoidStupidWarnings.h"
  7.  
  8. @implementation WWButtonCell
  9.  
  10.  
  11. + initialize { [WWButtonCell setVersion:3]; return self; }
  12. ////////////////////////////////////////////////////////
  13. //
  14. - init
  15. {
  16.   [super init];
  17.   controlStringSize = 32;
  18.   controlString = (char *)NXZoneCalloc([self zone], controlStringSize, sizeof(char));
  19.   sprintfControlString = (char *)NXZoneCalloc([self zone], controlStringSize, sizeof(char));
  20.   tclExpressionSize = 32;
  21.   tclExpression = (char *)NXZoneCalloc([self zone], tclExpressionSize, sizeof(char));
  22.   tclVarSize = 32;
  23.   tclVar = (char *)NXZoneCalloc([self zone], tclVarSize, sizeof(char));
  24.   tclCommandSize = 32;
  25.   tclCommand = (char *)NXZoneCalloc([self zone], tclCommandSize, sizeof(char));
  26.   interp = nil;
  27.   tclCommandDirty = YES;
  28.  
  29.   return self;
  30. }
  31. //
  32. - awake
  33. {
  34.   [super awake];
  35.   tclCommandDirty = YES;
  36.   return self;
  37. }
  38.  
  39. - free
  40. {
  41.   if (controlString) { NXZoneFree([self zone], controlString); }
  42.   if (sprintfControlString) { NXZoneFree([self zone], sprintfControlString); }
  43.   if (tclExpression) { NXZoneFree([self zone], tclExpression); }
  44.   if (tclVar) { NXZoneFree([self zone], tclVar); }
  45.   if (tclCommand) { NXZoneFree([self zone], tclCommand); }
  46.   return [super free];
  47. }
  48.  
  49. - reinitializeControlStringAndTclVarFromZone:(NXZone *)zone
  50. {
  51.   controlString = (char *)NXZoneCalloc(zone, controlStringSize, sizeof(char));
  52.   sprintfControlString = (char *)NXZoneCalloc(zone, controlStringSize, sizeof(char));
  53.   tclExpression = (char *)NXZoneCalloc(zone, tclExpressionSize, sizeof(char));
  54.   tclVar = (char *)NXZoneCalloc(zone, tclVarSize, sizeof(char));
  55.   tclCommand = (char *)NXZoneCalloc(zone, tclCommandSize, sizeof(char));
  56.   return self;
  57. }
  58.  
  59. - copyFromZone:(NXZone *)zone
  60. {
  61.   id newCopy = [super copyFromZone:zone];
  62.  
  63.  
  64.   [newCopy reinitializeControlStringAndTclVarFromZone:zone];
  65.   [newCopy setControlString:controlString];
  66.   [newCopy setTclExpression:tclExpression];
  67.   [newCopy setTclVar:tclVar];
  68.   [newCopy setTclCommand:tclCommand];
  69.  
  70.   return newCopy;
  71. }
  72.  
  73. - setInterp:newInterp { interp = newInterp; return self; }
  74. - interp { return interp; }
  75.  
  76. - resizeTclCommandForArgVector:(char *)argOrderVector
  77. {
  78.   BOOL    done = NO;
  79.   
  80.  
  81.   if (!done && !strcmp("d", argOrderVector))
  82.   {  while (tclCommandSize < (controlStringSize + 32))
  83.      {  if (!tclCommandSize)
  84.     {  tclCommandSize = 32;
  85.            tclCommand = (char *)NXZoneCalloc([self zone], tclCommandSize, sizeof(char));
  86.         }
  87.         else
  88.         {  tclCommandSize *= 2;
  89.            tclCommand = (char *)NXZoneRealloc([self zone], tclCommand, tclCommandSize);
  90.         }
  91.      }
  92.      done = YES;
  93.   }
  94.   if (!done && !strcmp("T", argOrderVector))
  95.   {  while (tclCommandSize < (controlStringSize + 32))
  96.      {  if (!tclCommandSize)
  97.     {  tclCommandSize = 32;
  98.            tclCommand = (char *)NXZoneCalloc([self zone], tclCommandSize, sizeof(char));
  99.         }
  100.         else
  101.         {  tclCommandSize *= 2;
  102.            tclCommand = (char *)NXZoneRealloc([self zone], tclCommand, tclCommandSize);
  103.         }
  104.      }
  105.      done = YES;
  106.   }
  107.   if (!done && !strcmp("f", argOrderVector))
  108.   {  while (tclCommandSize < (controlStringSize + 32) )
  109.      {  if (!tclCommandSize)
  110.     {  tclCommandSize = 32;
  111.            tclCommand = (char *)NXZoneCalloc([self zone], tclCommandSize, sizeof(char));
  112.         }
  113.         else
  114.         {  tclCommandSize *= 2;
  115.            tclCommand = (char *)NXZoneRealloc([self zone], tclCommand, tclCommandSize);
  116.         }
  117.      }
  118.      done = YES;
  119.   }
  120.  
  121.   if (!done && !strcmp("s", argOrderVector))
  122.   {  const char  *str = [self stringValue]; 
  123.      int   strLen = strlen(str);
  124.  
  125.      while (tclCommandSize < (controlStringSize + strLen))
  126.      {  if (!tclCommandSize)
  127.     {  tclCommandSize = 32;
  128.            tclCommand = (char *)NXZoneCalloc([self zone], tclCommandSize, sizeof(char));
  129.         }
  130.         else
  131.         {  tclCommandSize *= 2;
  132.            tclCommand = (char *)NXZoneRealloc([self zone], tclCommand, tclCommandSize);
  133.         }
  134.      }
  135.      done = YES;
  136.   }
  137.   // those were the easy ones; now for the permutations...
  138.  
  139.   return self;
  140. }
  141.  
  142.  
  143. - updateTclCommand
  144. {
  145.   char    *controlStringPtr, *sprintfControlStringPtr;
  146.   BOOL    done;
  147.   int     argOrderSize = 32;
  148.   char    *argOrderVector = (char *)NXZoneCalloc([self zone], argOrderSize, sizeof(char));
  149.   int     argOrderOffset = 0;
  150.  
  151.  
  152.   if (!controlString)
  153.   {  return nil;
  154.   }
  155.  
  156.   // we want to grovel over the controlString, 
  157.   // for right now, we really only tend to have the following patterns 
  158.   // in the controlString: 1 %f, 1 %d, 1 %s, %R, %G, %B, 1 %T
  159.   controlStringPtr = controlString;
  160.   sprintfControlStringPtr = sprintfControlString;
  161.   strcpy(sprintfControlString, controlString);
  162.   while (*controlStringPtr)
  163.   {  if (*controlStringPtr == '%')
  164.      {  sprintfControlStringPtr++;  controlStringPtr++;
  165.         if (*controlStringPtr)
  166.         {  switch (*controlStringPtr)
  167.            {  case 'd':    while (argOrderOffset >= argOrderSize)
  168.                         {  argOrderSize *= 2;
  169.                            argOrderVector = (char *)NXZoneRealloc([self zone], argOrderVector, argOrderSize);
  170.                         }
  171.                         argOrderVector[argOrderOffset++] = 'd';
  172.                         sprintfControlStringPtr++; controlStringPtr++;
  173.             break;
  174.               case 'T':    while (argOrderOffset >= argOrderSize)
  175.                         {  argOrderSize *= 2;
  176.                            argOrderVector = (char *)NXZoneRealloc([self zone], argOrderVector, argOrderSize);
  177.                         }
  178.                         argOrderVector[argOrderOffset++] = 'T';
  179.                         *sprintfControlStringPtr++ = 'd'; controlStringPtr++;
  180.             break;
  181.               case 'f':    while (argOrderOffset >= argOrderSize)
  182.                         {  argOrderSize *= 2;
  183.                            argOrderVector = (char *)NXZoneRealloc([self zone], argOrderVector, argOrderSize);
  184.                         }
  185.                         argOrderVector[argOrderOffset++] = 'f';
  186.                         sprintfControlStringPtr++; controlStringPtr++;
  187.             break;
  188.               case 's':    while (argOrderOffset >= argOrderSize)
  189.                         {  argOrderSize *= 2;
  190.                            argOrderVector = (char *)NXZoneRealloc([self zone], argOrderVector, argOrderSize);
  191.                         }
  192.                         argOrderVector[argOrderOffset++] = 's';
  193.                         sprintfControlStringPtr++; controlStringPtr++;
  194.             break;
  195.               case '%':    sprintfControlStringPtr++; controlStringPtr++;
  196.                         break;
  197.                default:    NXLogError("WWSliderCell: unknown specifier <%c> in controlString.\n", *controlStringPtr);
  198.                         sprintfControlStringPtr++; controlStringPtr++;
  199.             break;
  200.            }
  201.        }
  202.      }
  203.      else
  204.      {  sprintfControlStringPtr++;  controlStringPtr++;
  205.      }
  206.   }
  207.   argOrderVector[argOrderOffset] = 0;
  208.  
  209.   done = NO;
  210.  
  211.   if (!done && !strcmp("d", argOrderVector))
  212.   {  [self resizeTclCommandForArgVector:argOrderVector];
  213.      sprintf(tclCommand, sprintfControlString, [self intValue]);
  214.      done = YES;
  215.   }
  216.   if (!done && !strcmp("f", argOrderVector))
  217.   {  [self resizeTclCommandForArgVector:argOrderVector];
  218.      sprintf(tclCommand, sprintfControlString, [self floatValue]);
  219.      done = YES;
  220.   }
  221.   if (!done && !strcmp("s", argOrderVector))
  222.   {  [self resizeTclCommandForArgVector:argOrderVector];
  223.      sprintf(tclCommand, sprintfControlString, [self stringValue]);
  224.      done = YES;
  225.   }
  226.   if (!done && !strcmp("T", argOrderVector))
  227.   {  [self resizeTclCommandForArgVector:argOrderVector];
  228.      sprintf(tclCommand, sprintfControlString, [self tag]);
  229.      done = YES;
  230.   }
  231.   if (!done && !strcmp("dT", argOrderVector))
  232.   {  [self resizeTclCommandForArgVector:argOrderVector];
  233.      sprintf(tclCommand, sprintfControlString, [self intValue], [self tag]);
  234.      done = YES;
  235.   }
  236.   if (!done && !strcmp("fT", argOrderVector))
  237.   {  [self resizeTclCommandForArgVector:argOrderVector];
  238.      sprintf(tclCommand, sprintfControlString, [self floatValue], [self tag]);
  239.      done = YES;
  240.   }
  241.   if (!done && !strcmp("sT", argOrderVector))
  242.   {  [self resizeTclCommandForArgVector:argOrderVector];
  243.      sprintf(tclCommand, sprintfControlString, [self stringValue], [self tag]);
  244.      done = YES;
  245.   }
  246.   if (!done && !strcmp("Td", argOrderVector))
  247.   {  [self resizeTclCommandForArgVector:argOrderVector];
  248.      sprintf(tclCommand, sprintfControlString, [self tag], [self intValue]);
  249.      done = YES;
  250.   }
  251.   if (!done && !strcmp("Tf", argOrderVector))
  252.   {  [self resizeTclCommandForArgVector:argOrderVector];
  253.      sprintf(tclCommand, sprintfControlString, [self tag], [self floatValue]);
  254.      done = YES;
  255.   }
  256.   if (!done && !strcmp("Ts", argOrderVector))
  257.   {  [self resizeTclCommandForArgVector:argOrderVector];
  258.      sprintf(tclCommand, sprintfControlString, [self tag], [self stringValue]);
  259.      done = YES;
  260.   }
  261.  
  262.   if (!done)
  263.   {  while (tclCommandSize < controlStringSize)
  264.      {  if (!tclCommandSize)
  265.     {  tclCommandSize = 32;
  266.            tclCommand = (char *)NXZoneCalloc([self zone], tclCommandSize, sizeof(char));
  267.         }
  268.         else
  269.         {  tclCommandSize *= 2;
  270.            tclCommand = (char *)NXZoneRealloc([self zone], tclCommand, tclCommandSize);
  271.         }
  272.      }
  273.      strcpy(tclCommand, controlString);
  274.   }
  275.   tclCommandDirty = NO;
  276.  
  277.   NXZoneFree([self zone], argOrderVector);
  278.  
  279.   return self;
  280. }
  281.  
  282.  
  283. - evaluateSelf
  284. {
  285.    int   ret;
  286.    char  *newStringValue;
  287.    id    retID;
  288.  
  289.  
  290.   newStringValue = [interp globalEval:tclExpression :&ret];
  291.   if ((ret == TCL_OK) || (ret == TCL_RETURN))
  292.   {  [self setStringValue:newStringValue];
  293.      retID = self;
  294.   }
  295.   else
  296.   {  NXLogError("WWSliderCell: error <%s> evaluating tcl expression <%s>\n", 
  297.         newStringValue, tclExpression);
  298.      if (newStringValue) { free(newStringValue); }
  299.      retID = nil;
  300.   }
  301.   return retID;
  302. }
  303.  
  304. - updateInterp
  305. {
  306.   if ([interp eval:[self tclCommand]])
  307.   {  return self;
  308.   }
  309.   return nil;
  310. }
  311.  
  312. - setIntValue:(int)val
  313. {
  314.   [super setIntValue:val];
  315.   tclCommandDirty = YES;
  316.   return self;
  317. }
  318.  
  319. - setFloatValue:(float)val
  320. {
  321.   [super setFloatValue:val];
  322.   tclCommandDirty = YES;
  323.   return self;
  324. }
  325.  
  326. - setDoubleValue:(double)val
  327. {
  328.   [super setDoubleValue:val];
  329.   tclCommandDirty = YES;
  330.   return self;
  331. }
  332.  
  333. - setStringValue:(const char *)str
  334. {
  335.   [super setStringValue:str];
  336.   if (str && *str) 
  337.   {  [self setIntValue:atoi(str)];
  338.   }
  339.   else
  340.   {  [self setIntValue:0];
  341.   }
  342.   return self;
  343. }
  344.  
  345.  
  346. - setControlString:(const char *)str 
  347.   int   cnt;
  348.  
  349.  
  350.   if (!str) { return self; }
  351.   if (controlStringSize <= 0) 
  352.   {  controlStringSize = 32; 
  353.      controlString = (char *)NXZoneCalloc([self zone], controlStringSize, sizeof(char));
  354.   }
  355.   cnt = strlen(str);
  356.   while (cnt >= controlStringSize)
  357.   {  controlStringSize *= 2;
  358.      controlString = (char *)NXZoneRealloc([self zone], controlString, controlStringSize);
  359.   }
  360.   if (sprintfControlString)
  361.   {  sprintfControlString = (char *)NXZoneRealloc([self zone], sprintfControlString, controlStringSize);
  362.   }
  363.   else
  364.   {  sprintfControlString = (char *)NXZoneCalloc([self zone], controlStringSize, sizeof(char));
  365.   }
  366.   strcpy(controlString, str); 
  367.   tclCommandDirty = YES;
  368.   return self; 
  369. }
  370. //
  371. - (const char *)controlString { return controlString; }
  372.  
  373. - setTclExpression:(const char *)str 
  374.   int   cnt;
  375.  
  376.  
  377.   if (!str) { return self; }
  378.   if (tclExpressionSize <= 0) 
  379.   {  tclExpressionSize = 32; 
  380.      tclExpression = (char *)NXZoneCalloc([self zone], tclExpressionSize, sizeof(char));
  381.   }
  382.   cnt = strlen(str);
  383.   while (cnt >= tclExpressionSize)
  384.   {  tclExpressionSize *= 2;
  385.      tclExpression = (char *)NXZoneRealloc([self zone], tclExpression, tclExpressionSize);
  386.   }
  387.   strcpy(tclExpression, str); 
  388.   return self; 
  389. }
  390. //
  391. - (const char *)tclExpression { return tclExpression; }
  392.  
  393. - setTclVar:(const char *)str 
  394.   int   cnt;
  395.  
  396.  
  397.   if (!str) { return self; }
  398.   if (tclVarSize <= 0) 
  399.   {  tclVarSize = 32; 
  400.      tclVar = (char *)NXZoneCalloc([self zone], tclVarSize, sizeof(char));
  401.   }
  402.   cnt = strlen(str);
  403.   while (cnt >= tclVarSize)
  404.   {  tclVarSize *= 2;
  405.      tclVar = (char *)NXZoneRealloc([self zone], tclVar, tclVarSize);
  406.   }
  407.   strcpy(tclVar, str); 
  408.   return self; 
  409. }
  410. //
  411. - (const char *)tclVar { return tclVar; }
  412.  
  413. - setTclCommand:(const char *)str 
  414.   int   cnt;
  415.  
  416.  
  417.   if (!str) { return self; }
  418.   if (tclCommandSize <= 0) 
  419.   {  tclCommandSize = 32; 
  420.      tclCommand = (char *)NXZoneCalloc([self zone], tclCommandSize, sizeof(char));
  421.   }
  422.   cnt = strlen(str);
  423.   while (cnt >= tclCommandSize)
  424.   {  tclCommandSize *= 2;
  425.      tclCommand = (char *)NXZoneRealloc([self zone], tclCommand, tclCommandSize);
  426.   }
  427.   strcpy(tclCommand, str); 
  428.   return self; 
  429. }
  430. //
  431. - (const char *)tclCommand 
  432.   if (tclCommandDirty)
  433.   {  [self updateTclCommand];
  434.   }
  435.   return tclCommand; 
  436. }
  437.  
  438. - write:(NXTypedStream *)stream 
  439. {
  440.    [super write:stream];
  441.    NXWriteType(stream, "*", &controlString);
  442.    NXWriteType(stream, "*", &tclVar);
  443.    NXWriteType(stream, "*", &tclExpression);
  444.    NXWriteType(stream, "*", &tclCommand);
  445.    NXWriteObjectReference(stream, interp);
  446.    return self;
  447. }
  448. //
  449. - read:(NXTypedStream *)stream 
  450. {
  451.    int version;
  452.  
  453.    [super read:stream];
  454.  
  455.    version = NXTypedStreamClassVersion(stream, "WWButtonCell");
  456.    if (version == 1)
  457.    {  NXReadType(stream, "*", &controlString);
  458.       if (controlString) 
  459.       {  controlStringSize = strlen(controlString) + 1;
  460.          sprintfControlString = (char *)NXZoneCalloc([self zone], controlStringSize, sizeof(char));
  461.       }
  462.       else
  463.       {  controlStringSize = 0;
  464.          sprintfControlString = NULL;
  465.       }
  466.       NXReadType(stream, "*", &tclVar);
  467.       if (tclVar) 
  468.       {  tclVarSize = strlen(tclVar) + 1;
  469.       }
  470.       else
  471.       { tclVarSize = 0;
  472.       }
  473.       tclExpressionSize = 32;
  474.       tclExpression = (char *)NXZoneCalloc([self zone], tclExpressionSize, sizeof(char));
  475.    }
  476.    if (version == 2)
  477.    {  NXReadType(stream, "*", &controlString);
  478.       if (controlString) 
  479.       {  controlStringSize = strlen(controlString) + 1;
  480.          sprintfControlString = (char *)NXZoneCalloc([self zone], controlStringSize, sizeof(char));
  481.       }
  482.       else
  483.       {  controlStringSize = 0;
  484.          sprintfControlString = NULL;
  485.       }
  486.       NXReadType(stream, "*", &tclVar);
  487.       if (tclVar) 
  488.       {  tclVarSize = strlen(tclVar) + 1;
  489.       }
  490.       else
  491.       { tclVarSize = 0;
  492.       }
  493.       NXReadType(stream, "*", &tclExpression);
  494.       if (tclExpression) 
  495.       {  tclExpressionSize = strlen(tclExpression) + 1;
  496.       }
  497.       else
  498.       {  tclExpressionSize = 0;
  499.       }
  500.    }
  501.    if (version == 3)
  502.    {  NXReadType(stream, "*", &controlString);
  503.       if (controlString) 
  504.       {  controlStringSize = strlen(controlString) + 1;
  505.          sprintfControlString = (char *)NXZoneCalloc([self zone], controlStringSize, sizeof(char));
  506.       }
  507.       else
  508.       {  controlStringSize = 0;
  509.          sprintfControlString = NULL;
  510.       }
  511.       NXReadType(stream, "*", &tclVar);
  512.       if (tclVar) 
  513.       {  tclVarSize = strlen(tclVar) + 1;
  514.       }
  515.       else
  516.       { tclVarSize = 0;
  517.       }
  518.       NXReadType(stream, "*", &tclExpression);
  519.       if (tclExpression) 
  520.       {  tclExpressionSize = strlen(tclExpression) + 1;
  521.       }
  522.       else
  523.       {  tclExpressionSize = 0;
  524.       }
  525.       NXReadType(stream, "*", &tclCommand);
  526.       if (tclCommand) 
  527.       {  tclCommandSize = strlen(tclCommand) + 1;
  528.       }
  529.       else
  530.       {  tclCommandSize = 0;
  531.       }
  532.       interp = NXReadObject(stream);
  533.    }
  534.    return self;
  535. }
  536.  
  537. // IB stuff
  538. - (const char *)getInspectorClassName 
  539. {  
  540.    NXEvent  *event = [NXApp currentEvent];
  541.  
  542.    if (event->flags & NX_ALTERNATEMASK)
  543.    {  return [super getInspectorClassName];
  544.    }
  545.    
  546.    return "WWButtonCellIBInspector"; 
  547. }
  548.  
  549. @end
  550.